package com.dks.repository.impl.student;

import com.aliyuncs.utils.StringUtils;
import com.dks.dto.BaseIdRequestDto;
import com.dks.dto.TeacherCourseDto;
import com.dks.dto.student.LeaveDto;
import com.dks.dto.student.StudentClassTableDto;
import com.dks.dto.student.StudentTaskAddDto;
import com.dks.dto.student.TaskDto;
import com.dks.enumeration.*;
import com.dks.exception.BaseException;
import com.dks.mapper.*;
import com.dks.models.QsClass;
import com.dks.models.publicCompoment.PublicAttention;
import com.dks.models.publicCompoment.PublicDictionary;
import com.dks.models.publicCompoment.PublicThumbsUp;
import com.dks.models.student.StudentClass;
import com.dks.repository.IStudentClassRepository;
import com.dks.result.Result;
import com.dks.result.ResultInfo;
import com.dks.result.ResultModel;
import com.dks.util.IntegerUtils;
import com.dks.util.PageInfo;
import com.dks.util.TimeUtils;
import com.dks.vo.student.StudentTaskVo;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.jsonwebtoken.lang.Collections;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Repository
public class StudentClassRepository implements IStudentClassRepository {

    @Autowired
    private StudentClassMapper studentClassMapper;
    @Autowired
    private PublicDictionaryMapper publicDictionaryMapper;
    @Autowired
    private QsClassMapper qsClassMapper;
    @Autowired
    private PublicThumbsUpMapper publicThumbsUpMapper;
    @Autowired
    private PublicAttentionMapper publicAttentionMapper;

    /**
     * 作业提交
     *
     * @author evan
     */
    @Override
    public ResultModel<Boolean> addTask(StudentTaskAddDto studentTaskAddDto) {
        StudentClass studentClass = new StudentClass();
        BeanUtils.copyProperties(studentTaskAddDto, studentClass);
        int i = studentClassMapper.addTask(studentClass);
        if (i > 0) {
            return Result.makeResult(ResultInfo.SUCCESS, true);
        } else {
            return Result.makeResult(ResultInfo.ERR_STUDENT_001);
        }
    }

    /**
     * 作业查询-列表
     * 查询条件：班级id(qsClassId)、学生id(studentId)
     *
     * @author evan
     */
    @Override
    public ResultModel<PageInfo<StudentTaskVo>> listTask(Long userId, Long parentId, Long qsClassId, Long studentId, Integer status, Integer pageNum, Integer pageSize) {
        Page p = PageHelper.startPage(pageNum, pageSize);
        List<StudentTaskVo> studentClassList = studentClassMapper.listTask(parentId, qsClassId, studentId, status);
        if (Collections.isEmpty(studentClassList)) {
            return Result.makeResult(ResultInfo.SUCCESS, null);
        }
        PageInfo<StudentTaskVo> pageInfo = new PageInfo<>(pageNum, pageSize, p.getTotal(), p.getPages(), studentClassList);
        if (userId != null) {
            studentClassList = pageInfo.getData().stream().map(
                    studentTaskVo -> {
                        PublicThumbsUp publicThumbsUp = publicThumbsUpMapper.select(PublicThumbsUpEntityType.STUDENT_TASK.name(), studentTaskVo.getId(), userId);
                        studentTaskVo.setTaskThumbsUpStatus(publicThumbsUp == null ? false : true);
                        return studentTaskVo;
                    }).collect(Collectors.toList());
        }
        PageInfo<StudentTaskVo> newPageInfo = new PageInfo<>(pageNum, pageSize, p.getTotal(), p.getPages(), studentClassList);
        return Result.makeResult(ResultInfo.SUCCESS, newPageInfo);
    }

    /***
     * 作业查询-详情
     * @author evan
     */
    @Override
    public ResultModel<StudentTaskVo> taskDetail(Long userId, Long taskId) {
        StudentTaskVo studentTaskVo = studentClassMapper.selectTaskById(taskId);
        if (studentTaskVo == null) {
            return Result.makeResult(ResultInfo.SUCCESS, null);
        }
        //查询点赞状态
        PublicThumbsUp publicThumbsUp = publicThumbsUpMapper.select(PublicThumbsUpEntityType.STUDENT_TASK.name(), studentTaskVo.getId(), userId);
        studentTaskVo.setTaskThumbsUpStatus(publicThumbsUp == null ? false : true);
        //查询关注状态
        PublicAttention publicAttention = publicAttentionMapper.select(PublicAttentionEntityType.TEACHER.name(), studentTaskVo.getId(), userId);
        studentTaskVo.setAttentionStatus(publicAttention == null ? false : true);
        return Result.makeResult(ResultInfo.SUCCESS, studentTaskVo);
    }

    @Override
    public ResultModel<Object> getStudentClassList(Long studentId, String beginTime, String endTime, Long courseCategoryId, String studentBirthDay, Integer pageNum, Integer pageSize) {
        Map<String, Object> map = new HashMap<>();
        map.put("beginTime", beginTime);
        map.put("endTime", endTime);
        map.put("courseCategoryId", courseCategoryId);
        map.put("studentId", studentId);
        if (!StringUtils.isEmpty(studentBirthDay)) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            try {
                Date date = simpleDateFormat.parse(studentBirthDay);
                long birthMonth = ((new Date()).getTime() - date.getTime()) / 1000 / 60 / 60 / 24 / 30;
                map.put("babyBirthMonth", birthMonth);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        Page p = PageHelper.startPage(pageNum, pageSize);
        List<StudentClassTableDto> teacherList = studentClassMapper.getStudentClassTableDtoList(map);
        PageInfo<StudentClassTableDto> pageInfo = new PageInfo<>(pageNum, pageSize, p.getTotal(), p.getPages(), teacherList);
        return Result.makeResult(ResultInfo.SUCCESS, pageInfo);
    }

    @Override
    public ResultModel<Object> getStudentClassDetail(Long studentClassId) {
//        StudentC teacherList = studentClassMapper.getStudentClassTableDtoList(map);
        Map<String, Object> params = new HashMap<>();
        params.put("studentClassId", studentClassId);
        StudentClassTableDto studentClassTableDto = studentClassMapper.getStudentClassDetail(params);
        return Result.makeResult(ResultInfo.SUCCESS, studentClassTableDto);
    }

    @Override
    public ResultModel<Object> getTaskRequirement(Long classId) {
        QsClass qsClass = qsClassMapper.select(classId);
        if (qsClass == null) {
            return Result.makeResult(ResultInfo.ERR_CLASS_001);
        }
        TaskDto taskDto = qsClassMapper.getTaskRequirementByClassId(classId);
        return Result.makeResult(ResultInfo.SUCCESS, taskDto);
    }

    /**
     * 请假提交
     *
     * @param leaveDto id 班级id
     * @author evan
     */
    @Override
    public ResultModel<Boolean> leave(LeaveDto leaveDto) {
        LocalDateTime now = LocalDateTime.now();
        //查询请假班级
        List<StudentClass> studentClassList = studentClassMapper.list(leaveDto.getQsClassId(), leaveDto.getStudentId());
        if (Collections.isEmpty(studentClassList)) {
            return Result.makeResult(ResultInfo.ERR_STUDENT_CLASS_001, false);
        }
        StudentClass studentClass = studentClassList.get(0);
        //查询班级信息
        QsClass qsClass = qsClassMapper.select(studentClass.getQsClassId());
        if (qsClass == null) {
            return Result.makeResult(ResultInfo.ERR_CLASS_001, false);
        }
        //未签到状态才能请假
        if (!ClassAttendStatus.NOT_SIGN_IN.name().equals(studentClass.getClassAttendStatus())) {
            return Result.makeResult(ResultInfo.ERR_STUDENT_CLASS_002, false);
        }
        //单周请假次数限制
        List<PublicDictionary> leaveLimitWeekList = publicDictionaryMapper.getByType(DictionaryType.LEAVE_LIMIT_WEEK.name());
        Integer leaveLimitWeek = IntegerUtils.String2Integer(Collections.isEmpty(leaveLimitWeekList) ? null : leaveLimitWeekList.get(0).getDictData());
        if (leaveLimitWeek != null) {
            //查询该用户请假的周所有课程
            studentClassList = studentClassMapper.leaveList(leaveDto.getUserId(),
                    null, TimeUtils.getStartTimeOfWeek(qsClass.getLessonStartTime().toLocalDate()), TimeUtils.getEndTimeOfWeek(qsClass.getLessonStartTime().toLocalDate()));
            long leavedNum = studentClassList.stream().filter(sc -> ClassAttendStatus.LEAVE.name().equals(sc.getClassAttendStatus())).count();
            if (leavedNum >= (long) leaveLimitWeek) {
                return Result.makeResultAppend(ResultInfo.ERR_STUDENT_002, false, String.valueOf(leaveLimitWeek));
            }
        }
        //请假提前时间(小时)
        List<PublicDictionary> leaveBeforeTimeList = publicDictionaryMapper.getByType(DictionaryType.LEAVE_BEFORE_TIME.name());
        Integer leaveBeforeTime = IntegerUtils.String2Integer(Collections.isEmpty(leaveBeforeTimeList) ? null : leaveBeforeTimeList.get(0).getDictData());
        if (leaveBeforeTime != null && now.plusHours(leaveBeforeTime).isBefore(qsClass.getLessonStartTime())) {
            return Result.makeResultAppend(ResultInfo.ERR_STUDENT_003, String.valueOf(leaveLimitWeek));
        }
        //允许请假
        int i = studentClassMapper.leave(studentClass.getId(), leaveDto.getUserId(), now);
        // TODO  请假后需要还原课时 释放冻结课时 增加可用课时 @kenny
        if (i < 0) {
            return Result.makeResult(ResultInfo.ERR_STUDENT_004, false);
        } else {
            return Result.makeResult(ResultInfo.SUCCESS, true);
        }
    }

    /**
     * 停课提交--用户主动停课
     *
     * @author evan
     */
    @Override
    public ResultModel<Boolean> suspend(BaseIdRequestDto baseIdRequestDto) throws BaseException {
        LocalDateTime now = LocalDateTime.now();
        //TODO 停课
        return suspendClass(baseIdRequestDto.getId(), baseIdRequestDto.getUserId(), ClassAttendStatus.SUSPEND_PERSON);
    }

    /***
     * 停课操作
     * @param classAttendStatus SUSPEND_SYSTEM.系统停课 SUSPEND_PERSON.用户主动停课
     * @author evan
     */
    @Override
    @Transactional
    public ResultModel<Boolean> suspendClass(long seriesClassId, long userId, ClassAttendStatus classAttendStatus) throws BaseException {
        //查询停课课程
        List<StudentClass> studentClassList = studentClassMapper.seriesList(seriesClassId, userId, AppointmentType.FIXED.name(), LocalDateTime.now());
        if (Collections.isEmpty(studentClassList)) {
            return Result.makeResult(ResultInfo.ERR_STUDENT_CLASS_001, false);
        }
        //判断课程状态
        //1.是否有已经签到但是未确认的课程
        if (ClassAttendStatus.SIGN_IN.name().equals(studentClassList.get(0).getClassAttendStatus())) {
            return Result.makeResult(ResultInfo.ERR_STUDENT_CLASS_003, false);
        }
        //2.判断之后的课程是否已经停课
        if (ClassAttendStatus.SUSPEND_SYSTEM.name().equals(studentClassList.get(0).getClassAttendStatus())
                || ClassAttendStatus.SUSPEND_PERSON.name().equals(studentClassList.get(0).getClassAttendStatus())) {
            return Result.makeResult(ResultInfo.ERR_STUDENT_CLASS_004, false);
        }
        //停课 => 退课时
        for (StudentClass studentClass : studentClassList) {
            int i = studentClassMapper.suspendClass(studentClass.getId(), classAttendStatus.name());
            if (i <= 0) {
                throw new BaseException(ResultInfo.ERR_STUDENT_CLASS_005);
            }
            //TODO 退课时
        }
        return Result.makeResult(ResultInfo.SUCCESS, true);
    }


    /**
     * 停课提交--系统停课（定时器）
     * TODO 定时器
     *
     * @author evan
     */
    @Override
    public ResultModel<Boolean> suspendSystem(BaseIdRequestDto baseIdRequestDto) {
        return null;
    }


    public static void main(String[] args) {
        System.out.println(LocalDateTime.now().getDayOfWeek());
    }
}
